package yunquan.wang.modules.base.web;

import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;

import org.springframework.beans.BeanUtils;
import org.springframework.ui.jasperreports.JasperReportsUtils;
import org.springframework.web.util.WebUtils;

import yunquan.wang.modules.base.entity.ReportParameter;
import yunquan.wang.modules.base.service.ReportQueryService;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class ReportController {
	private static Map<String, Class<? extends JRAbstractExporter>> exportors;
	
	private static Map<String,String> contenType;
	static
	{
		contenType.put("cvs", "text/csv");
		contenType.put("html", "text/html");
		contenType.put("pdf", "application/pdf");
		contenType.put("xls", "application/vnd.ms-excel");
		
		
		exportors.put("cvs", JRCsvExporter.class);
		exportors.put("html", JRHtmlExporter.class);
		exportors.put("pdf", JRPdfExporter.class);
		exportors.put("xls", JRXlsExporter.class);
	}
	private String curentContentType;
	ReportQueryService reportQueryService;
	public   String report(HttpServletRequest request,HttpServletResponse response) throws Exception
	{
		String reportId=request.getParameter("reportId");
		String format=request.getParameter("format");
		curentContentType=contenType.get(format);
		List<ReportParameter> parameters=reportQueryService.getReportParameters(reportId);
		//get the report
		fillReportParam(parameters);
		JasperPrint jasperPrint=reportQueryService.generateJasperPrint(reportId,parameters);
		JRExporter exporter=BeanUtils.instantiateClass(exportors.get(format));
		exporter.setParameters(getExporterParameters());
		if(format.equals("csv" )||format.equals("html"))
		{
			renderReportUsingWriter(exporter,jasperPrint,response);
		} else
		{
			renderReportUsingOutputStream(exporter,jasperPrint,response);
		}
		return null;
	}
	
	public Map<JRExporterParameter,Object>   getExporterParameters() {
		Map<JRExporterParameter,Object> map=Maps.newHashMap();
	 map.put(net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI, "../reportimages?image=");
	 map.put(net.sf.jasperreports.engine.export.JRHtmlExporterParameter.CHARACTER_ENCODING, "UTF-8");
	 map.put(net.sf.jasperreports.engine.export.JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,true);
	 return map;
	}
	protected void renderReportUsingWriter(
			JRExporter exporter, JasperPrint populatedReport, HttpServletResponse response) throws Exception {
		// Copy the encoding configured for the report into the response.
		String contentType =curentContentType;
		String encoding = (String) exporter.getParameter(JRExporterParameter.CHARACTER_ENCODING);
		if (encoding != null) {
			// Only apply encoding if content type is specified but does not contain charset clause already.
			if (contentType != null && !contentType.toLowerCase().contains(WebUtils.CONTENT_TYPE_CHARSET_PREFIX)) {
				contentType = contentType + WebUtils.CONTENT_TYPE_CHARSET_PREFIX + encoding;
			}
		}
		response.setContentType(contentType);

		// Render report into HttpServletResponse's Writer.
		JasperReportsUtils.render(exporter, populatedReport, response.getWriter());
	}
	
	protected void renderReportUsingOutputStream(
			JRExporter exporter, JasperPrint populatedReport, HttpServletResponse response) throws Exception {
		// IE workaround: write into byte array first.
		ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
		JasperReportsUtils.render(exporter, populatedReport, baos);
		response.setContentType(curentContentType);
		response.setContentLength(baos.size());
		// Flush byte array to servlet output stream.
		ServletOutputStream out = response.getOutputStream();
		baos.writeTo(out);
		out.flush();
	}
/**
 * get report parameter
 * @param request
 * @return
 */
	public String reportParameter(HttpServletRequest request)
	{
		List<ReportParameter> parameters=Lists.newArrayList();//this is the parameter of report
		if(parameters.size()>0)
		{
			//
		 
		}
		
		return "";
	}
	
	private void fillReportParam(List<ReportParameter> parameters)
	{
		for(ReportParameter param:parameters)
		{
			 if(param.getFromtype().equalsIgnoreCase("request"))
			 {
				 param.setValue("");//Set the value
			 }
		}
	}
}
